import java.io.PrintWriter;

public class Facette {

	Point3D origine;	// La position de l'origine de la facette dans le repere du cadran
	Vecteur t1, t2;		// Les deux vecteurs definissant la facette dans le repere du cadran
	
	/** Cree une facette a partir d'un point et deux vecteurs
	 * @param a un point dans le cadran
	 * @param u un vecteur 
	 * @param v un vecteur non colineaire a u */
	public Facette(Point3D a, Vecteur u, Vecteur v) {
		origine = a;
		t1 = u;
		t2 = v;
	}
	
	/** Cree une facette a partir de trois points dans le cadran
	 * @param a un point dans le cadran
	 * @param u un point dans le cadran 
	 * @param v un point dans le cadran */
	public Facette(Point3D a, Point3D b, Point3D c) {
		origine = a;
		t1 = new Vecteur(a,b);
		t2 = new Vecteur(a,c);
	}
	
	/** Calcul la position de l'ombre du style sur la facette
	 * @param style un point dans le repere du cadran
	 * @param d un vecteur defini dans le repere du cadran
	 * @return la position de l'ombre du style sur la facette si elle existe, null sinon */
	public Point3D projete(Point3D style, Vecteur d) {
		//Vecteur s = new Vecteur(style,origine);
		Vecteur s = new Vecteur(origine,new Point3D(style.x,style.y,style.z));
		try {
			Matrice a = Matrice.passageM(t1,t2,d);
			Vecteur sol = s.applique(a);
			if(sol.get(1)<0||sol.get(2)<0||(sol.get(1)+sol.get(2))>1) { return null;}
			if(sol.get(3)>0) { return null;}
			Point3D ombre = new Point3D(style.x,style.y,style.z);
			ombre.translation(d.produit(-sol.get(3)));
			return ombre;
		} catch (IllegalArgumentException e) {
			return null; //matrice non inversible donc d parallele au plan de la facette
		}
	}
	
	public void ecrire(PrintWriter pw) {
		Point3D a = new Point3D(origine.x,origine.y,origine.y);
		Point3D b = new Point3D(origine.x,origine.y,origine.y);
		a.translation(t1);
		b.translation(t2);
		origine.ecrire(pw);
		a.ecrire(pw);
		b.ecrire(pw);
	}
	
	public Point3D getOrigine() {
		return origine;
	}

	public void setOrigine(Point3D origine) {
		this.origine = origine;
	}

	public Vecteur getU() {
		return t1;
	}

	public void setU(Vecteur u) {
		this.t1 = u;
	}

	public Vecteur getV() {
		return t2;
	}

	public void setV(Vecteur v) {
		this.t2 = v;
	}
}
